package mud.player;

import mud.Entity;
import mud.Exit;
import mud.Nameable;
import mud.Room;
import mud.Unit;
import mud.Visible;
import mud.events.AttackEvent;
import mud.events.Event;
import mud.events.LookEvent;

/** A unit that is remotely controlled by a human via a text interface */
public class PlayerUnit extends Unit {

    /** the remote client terminal */
    private final Terminal terminal;
    
    /**
     * Constructor
     * @param terminal the remote client terminal
     */
    public PlayerUnit(Terminal terminal) {
        this.terminal = terminal;
    }

    @Override
    public void observe(Event event) {
        if (event instanceof LookEvent) {
            LookEvent lookEvent = (LookEvent) event;
            Visible target = lookEvent.getTarget();
            Entity source = lookEvent.getSource();
            
            if (!target.equals(source.getRoom())) {
                terminal.println(getIdentifier(source) 
                    + " looks at " + getIdentifier((Entity) target) + ".");
            }
        } else if (event instanceof AttackEvent) {
            AttackEvent attackEvent = (AttackEvent) event;
            terminal.println(getIdentifier(attackEvent.getSource())
                + " attacks "  + getIdentifier((Entity) attackEvent.getTarget())
                + " for " + attackEvent.getDamage() + " damage.");
            
        }
    }

    @Override
    public void look(Visible target) {
        super.look(target);

        if (target instanceof Room) {
            terminal.println(Color.GREEN, 
                ((Room) target).getName());
        }
        
        String appearance = target.getAppearance();
        if (appearance != null) {
            terminal.println(appearance);
        } else {
            terminal.println(
                "There is nothing particularly noteworthy about "
                + getIdentifier((Entity) target) + ".");
        }

        if (target instanceof Room) {
            for (Entity occupant : ((Room) target).getOccupants()) {
                if (!occupant.equals(this)) {
                    terminal.println(
                        getIdentifier(occupant) + " is here.");
                }
            }
        }
    }

    /**
     * @return the remote client terminal
     */
    public Terminal getTerminal() {
        return terminal;
    }

    /**
     * Returns a string that identifies the given entity to this unit.
     * @param entity the entity to identify
     * @return a string that identifies the given entity
     */
    String getIdentifier(Entity entity) {
        if (entity instanceof Nameable) {
            return ((Nameable) entity).getName();
        }
        return "something";
    }

    /**
     * Attempts to return the user-specified target of an action
     * @param input the string containing a possible target identifier
     * @return the corresponding target, or null
     */
    Entity parseTarget(String input) {
        Entity target = null;
        for (Entity occupant : getRoom().getOccupants()) {
            if (occupant instanceof Nameable) {
                if (((Nameable) occupant).getName().equalsIgnoreCase(input)) {
                    target = occupant;
                    break;
                }
            }
        }
        return target;
    }

    /**
     * Attempts to return the user-specified exit
     * @param input the string containing a possible exit identifier
     * @return the corresponding exit, or null
     */
    public Exit parseExit(String input) {
        for (Exit exit : getRoom().getExits()) {
            if (exit.getName().equalsIgnoreCase(input)) {
                return exit;
            }
        }
        return null;
    }
}
